import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

public class ConnectionPool {
    //连接池 ：
    Vector<Connection> pool = new Vector<>();
    int initCount = 10;//初始化连接数
    int maxCount = 20;//最大连接数
    int usedCount = 0;//已经使用的连接数
    int currentCount = 20;//现有多少空闲连接数
    Connection connection = null;
    //初始化连接池
    public synchronized void initPool(){
        for (int i = 1; i < initCount; i++) {
            Connection connection = createConnection();
            pool.add(connection);
            currentCount++;
        }
    }
    //创建一个连接对象
    private synchronized Connection createConnection(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/empdb?characterencoding=utf8",
                    "root","root");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //重写当前生成Connection对象
        //connection 就是目标对象
        Object proxyObj = Proxy.newProxyInstance(Connection.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {
            //关闭连接
            //若池子中的连接数<initCount,将当前Connection对象放入pool
            //若pool中的连接数>=initCount,将当前Connection对象关闭 释放资源close
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                if (method.getName().equals("close")){
                    if (currentCount<initCount){
                        pool.add(connection);
                        currentCount++;
                        usedCount--;
                    }else {
                        result = method.invoke(connection,args);
                    }
                }else
                    result = method.invoke(connection,args);
                return result;
            }
        });



        return connection;
    }

    //获得一个连接对象
    public synchronized Connection getConnection(){
        //若pool中有空闲连接，则可以返回一个Connection对象
        if (currentCount>0){
            Connection connection = pool.remove(0);
            currentCount--;
            usedCount++;
            return connection;
        }else if (usedCount<maxCount){
            //若pool中没有空闲连接，若已使用的连接数<最大连接数，则创建一个Connection对象
            Connection connection = createConnection();
            usedCount++;
            return connection;
        }else
            //若pool中没有空闲连接，若以使用的连接数>=最大连接数，抛异常
            throw new RuntimeException("请等待");
    }
    //关闭连接池
    public synchronized void closePool(){
        currentCount = initCount;
        for (int i= pool.size()-1;i>=0;i--){
            Connection connection = pool.get(i);
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            pool.remove(connection);
        }
        currentCount=0;
        usedCount = 0;
    }
}
